/*******************************************************************************
 * Copyright (c) 2001, 2002 Boris Pruessmann and others. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Common Public License v0.5 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors: Boris Pruessmann - Initial implementation.
 ******************************************************************************/
package net.sourceforge.perforce.ui;

import com.google.common.collect.Lists;

import net.sourceforge.perforce.core.resources.RemoteFile;
import net.sourceforge.perforce.core.resources.RemoteResource;
import net.sourceforge.perforce.core.syncinfo.ResourceSyncInfo;

import org.eclipse.compare.BufferedContent;
import org.eclipse.compare.CompareUI;
import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.structuremergeviewer.IStructureComparator;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.swt.graphics.Image;
import org.eclipse.team.core.TeamException;

import java.io.InputStream;
import java.util.List;

/**
 * @version $Revision: 488 $
 * @author <a href="mailto:bpruessmann@users.sourceforge.net">Boris
 *         Pruessmann</a>
 */
public class PerforceResourceEditionNode extends BufferedContent implements IStructureComparator,
    ITypedElement {
  // ---------------------------------------------------------------------------
  // Private Variables

  /** Stores the remote resource. */
  private RemoteResource resource;
  /** Stores the children. */
  private Object[] children;

  // -------------------------------------------------------------------------
  // Public Constructors

  /**
   * Constructor for PerforceResourceEditionNode.
   * 
   * @param resource the remote resource.
   */
  public PerforceResourceEditionNode(RemoteResource resource) {
    this.resource = resource;
  }

  //----------------------------------------------------------------------------
  // -- Public Methods

  /**
   * Returns the associated RemoteResource.
   * 
   * @return the remote resource.
   */
  public RemoteResource getRemoteResource() {
    return resource;
  }

  /** @see IStructureComparator#getChildren() */
  public Object[] getChildren() {
    if (children == null) {
      if (resource == null) {
        children = new PerforceResourceEditionNode[0];
      } else {
        try {
          RemoteResource[] members = resource.members(new NullProgressMonitor());

          List<Object> tempChildren = Lists.newArrayListWithExpectedSize(members.length);
          for (int i = 0; i < members.length; i++) {
            RemoteResource remote = members[i];
            if (remote.isContainer()) {
              tempChildren.add(new PerforceResourceEditionNode(remote));
            } else {
              RemoteFile remoteFile = (RemoteFile) remote;
              ResourceSyncInfo syncInfo = remoteFile.getSyncInfo(null);
              if (syncInfo != null && !syncInfo.isDeleted()) {
                tempChildren.add(new PerforceResourceEditionNode(remote));
              }
            }
          }

          children = tempChildren.toArray();
        } catch (TeamException e) {
          PerforceUIPlugin.log(e.getStatus());
        }
      }
    }

    return children;
  }

  /** @see ITypedElement#getName() */
  public String getName() {
    return (resource == null) ? "" : resource.getName(); //$NON-NLS-1$
  }

  /** @see ITypedElement#getImage() */
  public Image getImage() {
    return CompareUI.getImage(resource);
  }

  /** @see ITypedElement#getType() */
  public String getType() {
    if (resource == null) {
      return UNKNOWN_TYPE;
    }

    if (resource.isContainer()) {
      return FOLDER_TYPE;
    }

    String name = resource.getName();
    name = name.substring(name.lastIndexOf('.') + 1);
    return (name.length() == 0) ? UNKNOWN_TYPE : name;
  }

  /**
   * Returns true if both resources names are identical. The content is not
   * considered.
   */
  @Override
  public boolean equals(Object other) {
    if (other instanceof ITypedElement) {
      String otherName = ((ITypedElement) other).getName();
      return getName().equals(otherName);
    }
    return super.equals(other);
  }

  @Override
  public int hashCode() {
    return getName().hashCode();
  }

  // ---------------------------------------------------------------------------
  // Protected Methods

  @Override
  protected InputStream createStream() throws CoreException {
    if (resource == null) {
      return null;
    }

    try {
      return resource.getContents(new NullProgressMonitor());
    } catch (TeamException e) {
      throw new CoreException(e.getStatus());
    }
  }
}
